package com.bulk.threadPool;

import cn.hutool.json.JSONUtil;
import lombok.SneakyThrows;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 异步编排测试
 *
 * @author 散装java
 */
public class CompletableTest {
    private String str = "{\"0\":\"pool-1-thread-1==0==1655515282609\",\"1\":\"pool-1-thread-2==1==1655515282609\",\"2\":\"pool-1-thread-2==2==1655515283623\",\"3\":\"pool-1-thread-3==3==1655515283623\",\"4\":\"pool-1-thread-1==4==1655515283623\",\"5\":\"pool-1-thread-4==5==1655515283623\",\"6\":\"pool-1-thread-3==6==1655515284626\",\"7\":\"pool-1-thread-3==7==1655515282609\",\"8\":\"pool-1-thread-4==8==1655515282609\",\"9\":\"main==9==1655515282609\"}";
    static ThreadPoolExecutor executor = new ThreadPoolExecutor(
            2,
            4,
            10,
            TimeUnit.SECONDS,
            new LinkedBlockingDeque<>(5),
            new ThreadPoolExecutor.CallerRunsPolicy());

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        List<CompletableFuture<Void>> list = new ArrayList<>();
        Map<Integer, String> map = new ConcurrentHashMap<>();
        long start = System.currentTimeMillis();
        for (int i = 0; i < 10; i++) {
            AtomicInteger integer = new AtomicInteger(i);
            CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
                String task = task(integer.get());
                map.put(integer.get(), task);
            }, executor);
            list.add(future);
        }
        CompletableFuture[] arr = list.toArray(new CompletableFuture[0]);
        CompletableFuture.allOf(arr).get();
        long end = System.currentTimeMillis();
        System.out.println("全部执行完毕后输出==" + (end - start));
        // 执行业务操作 ----
        System.out.println(JSONUtil.toJsonStr(map));
        executor.shutdown();
    }

    @SneakyThrows
    public static String task(int i) {
        // 模拟业务执行
        TimeUnit.SECONDS.sleep(1);
        String str = Thread.currentThread().getName() + "==" + i + "==" + System.currentTimeMillis();
        System.out.println(str);
        return str;
    }
}
